package articles_api

import (
	"context"
	"gin_study_blog/common"
	"gin_study_blog/common/blog_type"
	"gin_study_blog/common/http"
	"gin_study_blog/models"
	"gin_study_blog/utils"
	"github.com/fatih/structs"
	"github.com/gin-gonic/gin"
	"time"
)

type ArticleModifyRequest struct {
	ID           string          `json:"id"`
	Title        string          `json:"title"`        // 文章标题
	Introduction string          `json:"introduction"` // 文章简介
	Content      string          `json:"content"`      // 文章内容
	Category     string          `json:"category"`     // 文章分类
	Source       string          `json:"source"`       // 文章来源
	Link         string          `json:"link"`         // 原文链接
	BannerID     uint            `json:"banner_id"`    // 封面id
	Tags         blog_type.Array `json:"tags"`         // 文章标签
}

func (ArticlesApi) ArticleModifyView(c *gin.Context) {
	var cr ArticleModifyRequest
	err := c.ShouldBindJSON(&cr)
	if err != nil {
		common.Log.Error(err)
		http.FailWithError(err, &cr, c)
		return
	}

	// 不传 banner_id, 就在后台随机选一张
	var bannerUrl string
	if cr.BannerID != 0 {
		// 查询 banner
		err = common.DB.Model(models.BannerModel{}).Where("id = ?", cr.BannerID).Select("path").Scan(&bannerUrl).Error
		if err != nil {
			common.Log.Error(err.Error())
			http.FailWithMessage("图片不存在", c)
			return
		}
	}

	articleData := models.ArticleModel{
		UpdatedAt:    time.Now().Format("2006-01-02 15:04:05"),
		Title:        cr.Title,
		Keywords:     cr.Title,
		Introduction: cr.Introduction,
		Content:      cr.Content,
		Category:     cr.Category,
		Source:       cr.Source,
		Link:         cr.Link,
		BannerID:     cr.BannerID,
		BannerUrl:    bannerUrl,
		Tags:         cr.Tags,
	}
	// 检查文章是否存在
	err = articleData.ArticleIsExist(cr.ID)
	if err != nil {
		common.Log.Error(err.Error())
		http.FailWithMessage("文章不存在", c)
		return
	}

	maps := structs.Map(&articleData)
	// 去掉空值
	var mapNotEmpty = map[string]any{}
	for key, v := range maps {
		switch val := v.(type) {
		case string:
			if val == "" {
				continue
			}
		case blog_type.Array:
			if len(val) == 0 {
				continue
			}
		case int:
			if val == 0 {
				continue
			}
		case uint:
			if val == 0 {
				continue
			}
		case []string:
			if len(val) == 0 {
				continue
			}
		}
		mapNotEmpty[key] = v
	}

	// 更新成功, 同步数据到全文索引
	newArticle, _ := utils.CommDetail(cr.ID)

	err = ArticleModify(cr.ID, mapNotEmpty)
	if err != nil {
		common.Log.Error(err)
		http.FailWithMessage("更新失败", c)
		return
	}

	// 先删除与文章关联的全文搜索记录, 然后在添加
	if (articleData.Content != newArticle.Content) || (articleData.Title != newArticle.Title) {
		// 先删除
		utils.DeleteFullTextByArticleID(cr.ID)
		// 同步
		utils.AsyncArticleByFullText(cr.ID, cr.Title, cr.Content)
	}
	http.IsOkWithMessage("更新成功", c)
}

func ArticleModify(id string, data map[string]any) error {
	_, err := common.EsClient.Update().
		Index(models.ArticleModel{}.Index()).
		Id(id).Doc(data).
		Do(context.Background())
	return err
}
